// Request.cs
//
//  Copyright (C) 2008 George Talusan
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
//

using System.IO;
using System.Text;
using System.Web;
using System;

namespace Mono.Picnik.Core
{
	public class Request
	{
		public delegate void ExportedHandler (Request request);
		
		public event ExportedHandler Exported;

		public Request ()
		{
		}

		private string _method;
		public string Method
		{
			get { return _method ?? Constants.METHOD_POST; }
			set { _method = value; }
		}

#region IMPORTING
		private string _import;
		public string Import
		{
			get { return _import; }
			set { _import = value; }
		}

		private string _returntype;
		public string Returntype
		{
			get { return _returntype ?? Constants.VALUE_RETURNTYPE_LOAD; }
			set { _returntype = value; }
		}
#endregion

#region EXPORTING
		private string _export;
		public string Export
		{
			get { return _export; }
			set { _export = value; }
		}

		private string _export_agent;
		public string ExportAgent
		{
			get { return _export_agent ?? Constants.VALUE_EXPORT_AGENT_DEFAULT; }
			set
			{
				if (String.Compare (value, Constants.VALUE_EXPORT_AGENT_DEFAULT) != 0
					&& String.Compare (value, Constants.VALUE_EXPORT_AGENT_BROWSER) != 0)
				{
					throw new ArgumentException ("value must be one of picnik.com or browser");
				}
				_export_agent = value;
			}
		}

		private string _export_field;
		public string ExportField
		{
			get { return _export_field ?? Constants.VALUE_EXPORT_FIELD_DEFAULT; }
			set { _export_field = value; }
		}

		private string _export_method;
		public string ExportMethod
		{
			get { return _export_method ?? Constants.METHOD_POST; }
			set
			{
				if (String.Compare (value, Constants.METHOD_POST) != 0
					&& String.Compare (value, Constants.METHOD_GET) != 0)
				{
					throw new ArgumentException ("value must be one of POST or GET");
				}
				_export_method = value;
			}
		}

		private string _export_title;
		public string ExportTitle
		{
			get { return _export_title ?? Constants.VALUE_EXPORT_TITLE_DEFAULT; }
			set { _export_title = value; }
		}

		private string _imageid;
		public string ImageID
		{
			get { return _imageid; }
			set { _imageid = value; }
		}

		private string _original_thumb;
		public string OriginalThumb
		{
			get { return _original_thumb; }
			set { _original_thumb = value; }
		}

		private string _redirect;
		public string Redirect
		{
			get { return _redirect; }
			set { _redirect = value; }
		}

		private string _replace;
		public string Replace
		{
			get { return _replace ?? Constants.VALUE_REPLACE_NO; }
			set
			{
				if (String.Compare (value, Constants.VALUE_REPLACE_ASK) != 0
					&& String.Compare (value, Constants.VALUE_REPLACE_CONFIRM) != 0
					&& String.Compare (value, Constants.VALUE_REPLACE_YES) != 0
					&& String.Compare (value, Constants.VALUE_REPLACE_NO) != 0)
				{
					throw new ArgumentException ("value must be one of ask, confirm, yes, or no");
				}
				_replace = value;
			}
		}
#endregion

#region APPEARANCE
		private string _exclude;
		public string Exclude
		{
			get { return _exclude; }
			set
			{
				if (String.Compare (value, Constants.VALUE_EXCLUDE_IN) != 0
					&& String.Compare (value, Constants.VALUE_EXCLUDE_EDIT) != 0
					&& String.Compare (value, Constants.VALUE_EXCLUDE_CREATE) != 0
					&& String.Compare (value, Constants.VALUE_EXCLUDE_OUT) != 0)
				{
					throw new ArgumentException ("value must be one of in, edit, create, or out");
				}
				_exclude = value;
			}
		}

		private string _host_name;
		public string HostName
		{
			get { return _host_name; }
			set { _host_name = value; }
		}
#endregion

#region NAVIGATION
		private string _default_in;
		public string DefaultIn
		{
			get { return _default_in ?? Constants.VALUE_DEFAULT_IN_UPLOAD; }
			set { _default_in = value; }
		}

		private string _default_out;
		public string DefaultOut
		{
			get { return _default_out ?? Constants.VALUE_DEFAULT_OUT_DOWNLOAD; }
			set { _default_out = value; }
		}

		private string _page;
		public string Page
		{
			get { return _page; }
			set { _page = value; }
		}

		private string _close_target;
		public string CloseTarget
		{
			get { return _close_target; }
			set { _close_target = value; }
		}

		private string _expand_button;
		public string ExpandButton
		{
			get { return _expand_button ?? Constants.VALUE_EXPAND_BUTTON_TRUE; }
			set
			{
				if (String.Compare (value, Constants.VALUE_EXPAND_BUTTON_TRUE) != 0
					&& String.Compare (value, Constants.VALUE_EXPAND_BUTTON_FALSE) != 0)
				{
					throw new ArgumentException ("value must one of true or false");
				}
				_expand_button = value;
			}
		}
#endregion

		private byte[] _response;
		public byte[] ResponseAsBytes
		{
			get { return _response; }
			set { _response = value; if (Exported != null) Exported (this);}
		}
		
		public Stream ResponseAsStream
		{
			get
			{
				MemoryStream ms = new MemoryStream ();
				ms.Write (ResponseAsBytes, 0, ResponseAsBytes.Length);
				return ms;
			}
		}

		public Uri ToUri ()
		{
			StringBuilder sb = new StringBuilder ();
			sb.AppendFormat ("{0}?{1}={2}&{3}={4}", Constants.SERVICE_URL,
			          Constants.PARAM_API_KEY, Constants.VALUE_API_KEY,
			          Constants.PARAM_RETURNTYPE, Returntype);
			
			if (Export != null)
			{
				sb.AppendFormat ("&{0}={1}", Constants.PARAM_EXPORT, HttpUtility.UrlEncode (Export));
				sb.AppendFormat ("&{0}={1}", Constants.PARAM_EXPORT_TITLE, HttpUtility.UrlEncode (ExportTitle));
				sb.AppendFormat ("&{0}={1}", Constants.PARAM_EXPORT_AGENT, ExportAgent);
				sb.AppendFormat ("&{0}={1}", Constants.PARAM_EXPORT_METHOD, ExportMethod);
				sb.AppendFormat ("&{0}={1}", Constants.PARAM_EXPORT_FIELD, ExportField);
				if (ImageID != null)
				{
					sb.AppendFormat ("&{0}={1}", Constants.PARAM_IMAGEID, ImageID);
				}
				if (OriginalThumb != null)
				{
					sb.AppendFormat ("&{0}={1}", Constants.PARAM_ORIGINAL_THUMB, OriginalThumb);
				}
				if (Redirect != null)
				{
					sb.AppendFormat ("&{0}={1}", Constants.PARAM_REDIRECT, Redirect);
				}
				if (Replace != null)
				{
					sb.AppendFormat ("&{0}={1}", Constants.PARAM_REPLACE, Replace);
				}
			}
			
			if (Exclude != null)
			{
				sb.AppendFormat ("&{0}={1}", Constants.PARAM_EXCLUDE, Exclude);
			}
			
			if (HostName != null)
			{
				sb.AppendFormat ("&{0}={1}", Constants.PARAM_HOST_NAME, HostName);
			}
			
			if (DefaultIn != null)
			{
				sb.AppendFormat ("&{0}={1}", Constants.PARAM_DEFAULT_IN, DefaultIn);
			}
			
			if (DefaultOut != null)
			{
				sb.AppendFormat ("&{0}={1}", Constants.PARAM_DEFAULT_OUT, DefaultOut);
			}
			
			if (Page != null)
			{
				sb.AppendFormat ("&{0}={1}", Constants.PARAM_PAGE, Page);
			}
			
			if (CloseTarget != null)
			{
				sb.AppendFormat ("&{0}={1}", Constants.PARAM_CLOSE_TARGET, CloseTarget);
			}
			
			if (ExpandButton != null)
			{
				sb.AppendFormat ("&{0}={1}", Constants.PARAM_EXPAND_BUTTON, ExpandButton);
			}

			return new Uri (sb.ToString ());
		}
	}
}
